package game.players.states;

import game.ball.SoccerBall;
import game.players.SoccerPlayer;
import game.players.actions.Pass;
import game.players.actions.Shoot;

import java.util.ArrayList;
import java.util.List;

import com.uqbar.vainilla.DeltaState;
import com.uqbar.vainilla.events.constants.Key;

public class UserWithBall extends PlayerState {
	
	List<SoccerPlayer> teammates;
	
	public UserWithBall(SoccerPlayer player) {
		super(player);
		this.teammates = this.getPlayer().getScene().getTeammates();
	}

	@Override
	public void update(DeltaState deltaState) {
		SoccerBall ball = this.getPlayer().getBall();
		if(deltaState.isKeyBeingHold(Key.LEFT) && this.getPlayer().getX() > 0)
			ball.moveNormally(-this.getPlayer().getMovementSpeed(), 0);
		if(deltaState.isKeyBeingHold(Key.RIGHT) && this.getPlayer().getX() < this.getPlayer().getGame().getDisplayWidth() - this.getPlayer().getAppearance().getWidth())
			ball.moveNormally(this.getPlayer().getMovementSpeed(), 0);
		if(deltaState.isKeyBeingHold(Key.UP) && this.getPlayer().getY() > 0)
			ball.moveNormally(0, -this.getPlayer().getMovementSpeed());
		if(deltaState.isKeyBeingHold(Key.DOWN) && this.getPlayer().getY() < this.getPlayer().getGame().getDisplayHeight() - this.getPlayer().getAppearance().getHeight())
			ball.moveNormally(0, this.getPlayer().getMovementSpeed());
		
		//tiro al arco
		if(deltaState.isKeyPressed(Key.Z)) {
			Shoot.execute(this.getPlayer(), ball);
		} else {
			//pase hacia arriba
			if(deltaState.isKeyPressed(Key.X) && deltaState.isKeyBeingHold(Key.UP))
				Pass.execute(this.getPlayer(),this.getUpClosestMate(),ball);			
			else {
				//pase hacia abajo
				if(deltaState.isKeyPressed(Key.X) && deltaState.isKeyBeingHold(Key.DOWN))
					Pass.execute(this.getPlayer(),this.getDownClosestMate(),ball);
				else {
					//pase hacia la izquierda
					if(deltaState.isKeyPressed(Key.X) && deltaState.isKeyBeingHold(Key.LEFT))
						Pass.execute(this.getPlayer(),this.getLeftClosestMate(),ball);
					else {
						//pase hacia la derecha
						if(deltaState.isKeyPressed(Key.X) && deltaState.isKeyBeingHold(Key.RIGHT))
							Pass.execute(this.getPlayer(),this.getRightClosestMate(),ball);
						else {
							//pase sin flechita, se la pasa al jugador mas cercano
							if(deltaState.isKeyPressed(Key.X))
								Pass.execute(this.getPlayer(),this.getClosestMate(),ball);
						}
					}						
				}					
			}
		}			
	}

	@Override
	public boolean isWithBall() {
		return true;
	}
	
	// PASES
	public SoccerPlayer getClosestMate(List<SoccerPlayer> mates){
		if(mates.isEmpty())
			return this.getClosestMate();
					
		double minDist = 10000;
		SoccerPlayer closestMate = null;
		for(SoccerPlayer sc : mates){
			if(!(this.getPlayer().equals(sc)) && this.getDistanceWith(this.getPlayer(), sc) < minDist){
				minDist = this.getDistanceWith(this.getPlayer(), sc);
				closestMate = sc;
			}	
		}
		return closestMate;
	}	
	
	public SoccerPlayer getClosestMate(){
		double minDist = 10000;
		SoccerPlayer closestMate = null;
		for(SoccerPlayer sc : this.teammates){
			if(!sc.equals(this.getPlayer()) && this.getDistanceWith(this.getPlayer(), sc) < minDist){
				minDist = this.getDistanceWith(this.getPlayer(), sc);
				closestMate = sc;
			}	
		}
		return closestMate;
	}
	
	public double getDistanceWith(SoccerPlayer p1,SoccerPlayer p2){
		return Math.sqrt(Math.pow(p2.getX()-p1.getX(),2) + Math.pow(p2.getY()-p1.getY(),2));
	}
	
	public List<SoccerPlayer> getMatesOnTheLeft(){
		List<SoccerPlayer> result = new ArrayList<SoccerPlayer>();
		for(SoccerPlayer sc : this.teammates){
			if(sc.getX() < this.getPlayer().getX())
				result.add(sc);
		}
		return result;
	}
	
	
	public SoccerPlayer getLeftClosestMate(){
		return this.getClosestMate(this.getMatesOnTheLeft());
	}
	
	public List<SoccerPlayer> getMatesOnTheRight(){
		List<SoccerPlayer> result = new ArrayList<SoccerPlayer>();
		for(SoccerPlayer sc : this.teammates){
			if(sc.getX() > this.getPlayer().getX())
				result.add(sc);
		}
		return result;
	}
	
	public SoccerPlayer getRightClosestMate(){
		return this.getClosestMate(this.getMatesOnTheRight());
	}
	
	public List<SoccerPlayer> getUpMates(){
		List<SoccerPlayer> result = new ArrayList<SoccerPlayer>();
		for(SoccerPlayer sc : this.teammates){
			if(sc.getY() < this.getPlayer().getY())
				result.add(sc);
		}
		return result;
	}
	
	public SoccerPlayer getUpClosestMate(){
		return this.getClosestMate(this.getUpMates());
	}
	
	public List<SoccerPlayer> getDownMates(){
		List<SoccerPlayer> result = new ArrayList<SoccerPlayer>();
		for(SoccerPlayer sc : this.teammates){
			if(sc.getY() > this.getPlayer().getY())
				result.add(sc);
		}
		return result;
	}
	
	public SoccerPlayer getDownClosestMate(){
		return this.getClosestMate(this.getDownMates());
	}

}
